<?php

namespace app\index\controller;

use think\Controller;
use think\Db;

/**
 * 任务计划控制器
 **/
class Plan extends Controller
{
    /**
     * 每天00:01的时候执行优惠券是否过期状态更新
     * */
    public function updateCoupon()
    {
        file_put_contents(RUNTIME_PATH . 'updateCoupon.txt', date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
        Db::name('user_coupon')->where(['status' => 1, 'expire_time' => ['lt', date('Y-m-d')]])->update(['status' => 3, 'update_time' => time()]);
    }

    /**
     * 自动确认收货
     * 每日凌晨00:20点执行
     * 根据任务表（shop_plan）执行对应 【确认收货】 任务
     * */
    public function executeConfirmGetOrderPlan()
    {
        file_put_contents(RUNTIME_PATH . 'executeConfirmGetOrderPlan.txt', date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
        $list = Db::name('plan')->where(['execute_date' => ['elt', date('Y-m-d')], 'type' => 2])->select();
        if ($list) {
            foreach ($list as &$v) {
                $order_info = Db::name('order')->where(['id' => $v['order_id']])->find();
                if ($order_info['status'] == 3) $this->confirmGetGoods($v['order_id']);
            }
        }
    }

    /**
     * 确认收货
     * */
    public function confirmGetGoods($id)
    {
        if (empty($id)) apiReturn(2, '订单ID缺失');

        $info = Db::name('order')->where(['id' => $id, 'is_del' => 0])->find();

        if ($info) {
            if ($info['status'] == 3) {
                Db::startTrans();
                try {
                    $time = time();
                    $order_data = array(
                        'status' => 4,
                        'update_time' => $time,
                        'complete_time' => $time
                    );
                    Db::name('order')->where(['id' => $id])->update($order_data);

                    // 收益解冻（直推收益，级差收益，服务津贴）
                    $profit_data = [
                        'status' => 2,
                        'update_time' => $time
                    ];
                    Db::name('profit')->where(['order_id' => $id, 'type' => ['IN', [1, 2, 3]]])->update($profit_data);

                    $profit_list = Db::name('profit')->where(['order_id' => $id, 'type' => ['IN', [1, 2, 3]]])->select();
                    if ($profit_list) {
                        foreach ($profit_list as &$v) {
                            Db::name('user')->where(['id' => $v['user_id']])->setInc('all_profit', $v['price']);
                        }
                    }

                    // 游客下单后变成VIP
                    $level = Db::name('user')->where(['id' => $info['user_id']])->value('level');
                    if ($level < 2) Db::name('user')->where(['id' => $info['user_id']])->setField('level', 2);

                    Db::name('user')->where(['id' => $info['user_id']])->setInc('all_consume', $info['pay_price']);

                    // 任务表新增 （用户 会员等级/档数 升级）任务  ==> 当前用户以及所有上级用户
                    if ($user_id = $info['user_id']) {
                        // 某个用户的级别变更需要将其所有上级都加入到用户升级的任务计划
                        addAllUpUserToUpPlan($user_id, true);
                    }

                    // 确认收货之后删除任务表 【确认收货】 任务
                    Db::name('plan')->where(['order_id' => $id, 'type' => 2])->delete();

                    Db::commit();
                } catch (\Exception $e) {
                    Db::rollback();
                }
            }
        }
    }

    /**
     * 销售月奖
     * 每月1号凌晨1点执行
     * */
    public function createSalesBonus()
    {
        file_put_contents(RUNTIME_PATH . 'createSalesBonus.txt', date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
        $bonus_rate = Db::name('sales_bonus_rate')->where(['name' => 'bonus_rate'])->value('value');
        if ($bonus_rate) {
            // 打成城市服务站后次月享受销售奖励；查询城市服务站用户ID

            // 查询上月第一天的时间戳
            $last_month_first_time = strtotime(date('Y-m-1', strtotime('last month')));
            // 查询上月最后一天的时间戳
            $last_month_last_time = strtotime(date('Y-m-1')) - 1;

            /**
             * 将条件控制在次月
             * city_time != 0 && (city_time < '. $last_month_first_time .' || (city_time >= '.  $last_month_first_time.' && city_time <= '. $last_month_last_time .'))
             * */
            $where = ' level = 5 && city_time != 0 && (city_time <= ' . $last_month_last_time . ') ';
            $user_ids_list = Db::name('user')->field('id')->where($where)->select();
            $user_ids = implode(',', array_column($user_ids_list, 'id'));

            if ($user_ids) {
                /**
                 * 上月总业绩：上月【已完成】的所有订单金额总和；
                 * 已完成：complete_time字段存在值
                 * */
                $all_price = Db::name('order')->where(['complete_time' => ['BETWEEN', [$last_month_first_time, $last_month_last_time]]])->sum('pay_price');

                $all_bonus = sprintf('%.2f', $all_price * $bonus_rate / 100);
                $data = [
                    'user_ids' => $user_ids,
                    'all_price' => $all_price,
                    'all_bonus' => $all_bonus,
                    'rate' => $bonus_rate,
                    'bonus_price' => $all_bonus / count($user_ids_list),
                    'year' => date('Y', $last_month_first_time),
                    'month' => date('m', $last_month_first_time),
                    'create_time' => time()
                ];
                Db::name('sales_bonus')->insert($data);
            }
        }
    }

    /**
     * 退休基金
     * 每月1号凌晨2点执行
     * */
    public function createSalesRetire()
    {
        file_put_contents(RUNTIME_PATH . 'createSalesRetire.txt', date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
        // 档数分成比例
        $first_gear_rate = Db::name('retire_fund_rule')->where(['name' => 'first_gear_rate'])->cache(3600)->value('value');
        $second_gear_rate = Db::name('retire_fund_rule')->where(['name' => 'second_gear_rate'])->cache(3600)->value('value');
        $third_gear_rate = Db::name('retire_fund_rule')->where(['name' => 'third_gear_rate'])->cache(3600)->value('value');

        // 查询上月第一天的时间戳
        $last_month_first_time = strtotime(date('Y-m-1', strtotime('last month')));
        // 查询上月最后一天的时间戳
        $last_month_last_time = strtotime(date('Y-m-1')) - 1;

        /**
         * 上月总业绩：上月【已完成】的所有订单金额总和；
         * 已完成：complete_time字段存在值
         * */
        $all_price = Db::name('order')->where(['complete_time' => ['BETWEEN', [$last_month_first_time, $last_month_last_time]]])->sum('pay_price');

        if ($all_price) {
            $time = time();
            $year = date('Y', $last_month_first_time);
            $month = date('m', $last_month_first_time);

            Db::startTrans();
            try {
                // 一档服务商总数量
                $where = ' gear = "first_gear" and first_gear_time != 0 && (first_gear_time <= ' . $time . ') ';
                $first_gear_user_list = Db::name('user')->field('id')->where($where)->select();
                $first_gear_user_count = count($first_gear_user_list);

                // 二档服务商总数量
                $where = ' gear = "second_gear" and second_gear_time != 0 && (second_gear_time <= ' . $time . ' || (second_gear_time BETWEEN ' . $last_month_first_time . ' AND ' . $time . ')) ';
                $second_gear_user_list = Db::name('user')->field('id')->where($where)->select();
                $second_gear_user_count = count($second_gear_user_list);

                // 三档服务商总数量
                $where = ' gear = "third_gear" and third_gear_time != 0 && (third_gear_time <= ' . $time . ' || (third_gear_time BETWEEN ' . $last_month_first_time . ' AND ' . $time . ')) ';
                $third_gear_user_list = Db::name('user')->field('id')->where($where)->select();
                $third_gear_user_count = count($third_gear_user_list);

                // 一档退休金额平均配额
                $first_gear_avg_price = ($all_price * $first_gear_rate / 100) / ($first_gear_user_count + $second_gear_user_count + $third_gear_user_count);
                // 一档退休基金总额
                $first_gear_all_price = $first_gear_avg_price * $first_gear_user_count;
                if ($first_gear_avg_price) {
                    $first_data = [
                        'user_ids' => implode(',', array_column($first_gear_user_list, 'id')),
                        'gear' => 'first_gear',
                        'all_price' => $all_price,
                        'all_retire_price' => $first_gear_all_price,
                        'rate' => $first_gear_rate,
                        'retire_price' => $first_gear_avg_price,
                        'year' => $year,
                        'month' => $month,
                        'create_time' => $time
                    ];
                    Db::name('retire_fund')->insert($first_data);
                }

                // 二档退休基金总额
                $second_gear_avg_price = ($all_price * $second_gear_rate / 100) / ($second_gear_user_count + $third_gear_user_count) + $first_gear_avg_price;
                // 二档退休金额平均配额
                $second_gear_all_price = $second_gear_avg_price * $second_gear_user_count;
                if ($second_gear_avg_price) {
                    $second_data = [
                        'user_ids' => implode(',', array_column($second_gear_user_list, 'id')),
                        'gear' => 'second_gear',
                        'all_price' => $all_price,
                        'all_retire_price' => $second_gear_all_price,
                        'rate' => $second_gear_rate,
                        'retire_price' => $second_gear_avg_price,
                        'year' => $year,
                        'month' => $month,
                        'create_time' => $time
                    ];
                    Db::name('retire_fund')->insert($second_data);
                }


                // 三档退休金额平均配额
                $third_gear_avg_price = ($all_price * $third_gear_rate / 100) / $third_gear_user_count + $second_gear_avg_price;
                // 三档退休基金总额
                $third_gear_all_price = $third_gear_avg_price * $third_gear_user_count;
                if ($third_gear_avg_price) {
                    $third_data = [
                        'user_ids' => implode(',', array_column($third_gear_user_list, 'id')),
                        'gear' => 'third_gear',
                        'all_price' => $all_price,
                        'all_retire_price' => $third_gear_all_price,
                        'rate' => $third_gear_rate,
                        'retire_price' => $third_gear_avg_price,
                        'year' => $year,
                        'month' => $month,
                        'create_time' => $time
                    ];
                    Db::name('retire_fund')->insert($third_data);
                }
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
            }
        }
    }

    /**
     * 区域门店补贴
     * 每月1号凌晨3点执行
     * */
    public function regionShopSubsidy()
    {
        file_put_contents(RUNTIME_PATH . 'regionShopSubsidy.txt', date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
        Db::startTrans();
        try {
            $shop_list = Db::name('shop')->where(['status' => 1, 'disable' => 1])->select();
            if ($shop_list) {
                $region_shop_rate = C('REGION_SHOP_RATE');

                if ($region_shop_rate) {
                    $time = time();
                    // 查询上月第一天的时间戳
                    $last_month_first_time = strtotime(date('Y-m-1', strtotime('last month')));
                    // 查询上月最后一天的时间戳
                    $last_month_last_time = strtotime(date('Y-m-1')) - 1;

                    $data = [];
                    foreach ($shop_list as &$v) {
                        if ($v['success_time'] < $last_month_first_time) {
                            // 上月之前就已经通过门店审核

                            $where['complete_time'] = ['BETWEEN', [$last_month_first_time, $last_month_last_time]];
                        } else if ($v['success_time'] >= $last_month_first_time && $v['success_time'] <= $last_month_last_time) {
                            // 上月通过审核
                            $start_time = strtotime(date('Y-m-d', $v['success_time'] + 24 * 3600));

                            $where['complete_time'] = ['BETWEEN', [$start_time, $last_month_last_time]];
                        }

                        $province = mb_substr($v['province'], 0, -1);
                        $city = mb_substr($v['city'], 0, -1);
                        $area = mb_substr($v['area'], 0, -1);

                        $where['get_province'] = ['LIKE', '%' . $province . '%'];
                        $where['get_city'] = ['LIKE', '%' . $city . '%'];
                        $where['get_area'] = ['LIKE', '%' . $area . '%'];

                        $all_region_price = Db::name('order')->where($where)->sum('pay_price');

                        file_put_contents(RUNTIME_PATH . 'regionShopSubsidyOrderList.txt', json_encode(Db::name('order')->field('id,pay_price')->where($where)->select()) . PHP_EOL, FILE_APPEND);

                        $data[] = [
                            'shop_id' => $v['id'],
                            'user_id' => $v['user_id'],
                            'all_price' => $all_region_price,
                            'rate' => $region_shop_rate,
                            'price' => sprintf('%.2f', $all_region_price * $region_shop_rate / 100),
                            'year' => date('Y', $last_month_first_time),
                            'month' => date('m', $last_month_first_time),
                            'create_time' => $time
                        ];
                    }

                    Db::name('shop_subsidy')->insertAll($data);
                }
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            file_put_contents(RUNTIME_PATH . 'errorToRegionShopSubsidy.txt', date('Y-m-d H:i:s') . '=======>' . $e . PHP_EOL . PHP_EOL, FILE_APPEND);
        }
    }

    /**
     * 用户 会员等级/档数 升级
     * 每日凌晨4点执行
     * 根据任务表（shop_plan）执行对应 【用户 会员等级/档数 升级】 任务
     * */
    public function executeUserUpPlan()
    {
        file_put_contents(RUNTIME_PATH . 'executeUserUpPlan.txt', date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
        $date = date('Y-m-d');
        $list = Db::name('plan')->where(['execute_date' => $date, 'type' => 1])->order('id asc')->select();
        if ($list) {
            foreach ($list as &$v) {
                $this->userUp($v['user_id']);
                Db::name('plan')->where(['id' => $v['id']])->delete();
            }
        }
    }

    /************************ 用户 会员等级/档数 升级 START ************************/
    /**
     * 查询用户的会员等级晋升是否满足条件
     * @param int $user_id    用户id
     * @param int $level      需要达到的等级
     * @param int $need_count 线路数量，当等于该数值用停止
     * @return bool
     * */
    public function userLevelUpCondition($user_id, $level, $need_count)
    {
        file_put_contents(RUNTIME_PATH . 'upUser.txt', '');
        //不同的线路
        getSonUserList($user_id, $diff_circuit_list);

        if ($diff_circuit_list) {
            $find_count = 0;
            $last_find_ids = [];
            foreach ($diff_circuit_list as &$v) {
                if (array_intersect($last_find_ids, $v)) {
                    continue;
                } else {
                    $id = Db::name('user')->where(['level' => $level, 'id' => ['IN', $v]])->value('id');
                    file_put_contents(RUNTIME_PATH . 'upUser.txt', '查询到用户ID：' . $id . '；sql：' . Db::name('user')->getLastSql() . PHP_EOL, FILE_APPEND);
                    if ($id) {
                        $last_find_ids = $v;
                        $find_count = $find_count + 1;
                        if ($find_count >= $need_count) {
                            return true;
                        }
                    }
                }
            }
            return false;
        } else {
            return false;
        }
    }

    /**
     * 查询用户的档数等级晋升是否满足条件
     * @param int $user_id    用户id
     * @param int $gear       需要达到的档数
     * @param int $need_count 线路数量，当等于该数值用停止
     * @return bool
     * */
    public function userGearUpCondition($user_id, $gear, $need_count)
    {
//        file_put_contents(RUNTIME_PATH . 'gearUser.txt', '');
        //不同的线路
        getSonUserList($user_id, $diff_circuit_list);

        if ($diff_circuit_list) {
            $find_count = 0;
            $last_find_ids = [];
            foreach ($diff_circuit_list as &$v) {
                if (array_intersect($last_find_ids, $v)) {
                    continue;
                } else {
                    switch ($gear) {
                        case '':
                            $where = ['level' => 5, 'id' => ['IN', $v]];
                            break;
                        case 'first_gear':
                            $where = ['gear' => 'first_gear', 'id' => ['IN', $v]];
                            break;
                        case 'second_gear':
                            $where = ['gear' => 'second_gear', 'id' => ['IN', $v]];
                            break;
                    }

                    $id = Db::name('user')->where($where)->value('id');
//                    file_put_contents(RUNTIME_PATH . 'gearUser.txt', '查询到用户ID：' . $id . '；sql：' . Db::name('user')->getLastSql() . PHP_EOL, FILE_APPEND);
                    if ($id) {
                        $last_find_ids = $v;
                        $find_count = $find_count + 1;
                        if ($find_count >= $need_count) {
                            return true;
                        }
                    }
                }
            }
            return false;
        } else {
            return false;
        }
    }

    /**
     * 用户 会员等级/档数 升级
     * */
    public function userUp($user_id)
    {
        $time = time();
        // 查询上级用户的会员等级
        $user_info = Db::name('user')->field('level,gear')->where(['id' => $user_id])->find();
        $level = $user_info['level'];
        $gear = $user_info['gear'];
        switch ($level) {
            case 2:
                // VIP

                /**
                 * 晋升社区服务站条件：
                 * 条件一：
                 * $community_vip_count：下级用户中需有 {$community_vip_count} 个VIP及以上等级
                 * $community_vip_consume：{$community_vip_count} 个VIP中均消费累计 {$community_vip_consume} 元
                 * 条件二：
                 * $community_own_consume：自行消费累计达 {$community_own_consume}
                 * */
                $community_vip_count = Db::name('user_up_rule')->where(['name' => 'community_vip_count'])->value('value');
                $community_vip_consume = Db::name('user_up_rule')->where(['name' => 'community_vip_consume'])->value('value');
                $community_own_consume = Db::name('user_up_rule')->where(['name' => 'community_own_consume'])->value('value');

                // 社区资格（下级用户中有$community_vip_count个VIP并且均累计消费$community_vip_consume）
                $where['up_user_id'] = $user_id;
                $where['level'] = 2;
                $where['all_consume'] = ['egt', $community_vip_consume];
                // 满足条件一数量
                $community_qualifications_count = Db::name('user')->where($where)->count();
                if ($community_qualifications_count >= $community_vip_count) {
                    // 满足条件二数量
                    $own_all_consume = Db::name('user')->where(['id' => $user_id])->value('all_consume');

                    if ($own_all_consume >= $community_own_consume) {
                        // 用户等级晋升社区服务站
                        $level_data = [
                            'level' => 3,
                            'update_time' => $time
                        ];
                        Db::name('user')->where(['id' => $user_id])->update($level_data);
                    }
                }
                break;
            case 3:
                // 社区服务站

                /**
                 * 晋升县区服务站条件：
                 * 条件一：自己是社区服务站
                 * 条件二：培育 {$county_diff_community_count} 个不同线社区服务站
                 * 条件三：总累计业绩达到 {$county_all_consume} 元
                 * */
                $county_diff_community_count = Db::name('user_up_rule')->where(['name' => 'county_diff_community_count'])->value('value');
                $county_all_consume = Db::name('user_up_rule')->where(['name' => 'county_all_consume'])->value('value');

                if ($this->allConsume($user_id) >= $county_all_consume) {
                    //满足条件三

                    if ($this->userLevelUpCondition($user_id, 3, $county_diff_community_count)) {
                        //满足条件二

                        // 用户等级晋升县区服务站
                        $level_data = [
                            'level' => 4,
                            'update_time' => $time
                        ];
                        Db::name('user')->where(['id' => $user_id])->update($level_data);
                    }
                }
                break;
            case 4:
                // 县区服务站

                /**
                 * 晋升城市服务站条件：
                 * 条件一：自己是县区服务站
                 * 条件二：培育 {$city_diff_county_count} 个不同线县区服务站
                 * 条件三：总累计业绩达到 {$city_all_consume} 元
                 * */
                $city_diff_county_count = Db::name('user_up_rule')->where(['name' => 'city_diff_county_count'])->value('value');
                $city_all_consume = Db::name('user_up_rule')->where(['name' => 'city_all_consume'])->value('value');

                if ($this->allConsume($user_id) >= $city_all_consume) {
                    //满足条件三

                    if ($this->userLevelUpCondition($user_id, 4, $city_diff_county_count)) {
                        //满足条件二

                        // 用户等级晋升城市服务站
                        $level_data = [
                            'level' => 5,
                            'city_time' => $time,
                            'is_change_level' => 0,
                            'update_time' => $time
                        ];
                        Db::name('user')->where(['id' => $user_id])->update($level_data);
                    }
                }
                break;
            case 5:
                // 城市服务站
                switch ($gear) {
                    case '':
                        // 城市服务站

                        /**
                         * 晋升一档服务商
                         * 条件一：自己是城市服务站
                         * 条件二：培育2个不同线城市服务站
                         * */
                        if ($this->userLevelUpCondition($user_id, 5, 2)) {
                            // 用户等级晋升城市服务站
                            $gear_data = [
                                'gear' => 'first_gear',
                                'first_gear_time' => $time,
                                'is_change_level' => 0,
                                'update_time' => $time
                            ];
                            Db::name('user')->where(['id' => $user_id])->update($gear_data);
                        }

                        break;
                    case 'first_gear':
                        // 一档服务商

                        /**
                         * 晋升二档服务商
                         * 条件一：自己是城市服务站
                         * 条件二：培育2个不同线一档服务商
                         * */
                        if ($this->userGearUpCondition($user_id, 'first_gear', 2)) {
                            // 用户等级晋升城市服务站
                            $gear_data = [
                                'gear' => 'second_gear',
                                'second_gear_time' => $time,
                                'is_change_level' => 0,
                                'update_time' => $time
                            ];
                            Db::name('user')->where(['id' => $user_id])->update($gear_data);
                        }

                        break;
                    case 'second_gear':
                        // 二档服务商

                        /**
                         * 晋升三档服务商
                         * 条件一：自己是城市服务站
                         * 条件二：培育2个不同线二档服务商
                         * */
                        if ($this->userGearUpCondition($user_id, 'second_gear', 2)) {
                            // 用户等级晋升城市服务站
                            $gear_data = [
                                'gear' => 'third_gear',
                                'third_gear_time' => $time,
                                'is_change_level' => 0,
                                'update_time' => $time
                            ];
                            Db::name('user')->where(['id' => $user_id])->update($gear_data);
                        }

                        break;
                }

                break;
        }
    }
    /************************ 用户 会员等级/档数 升级 END ************************/

    // 查询出的用户id集合
    public $search_user_ids = [];

    /**
     * 获取某一个用户的所有下级用户id集合
     * @param int/array $in_user_id 用户id
     * @return array
     * */
    public function getSonUserIds($in_user_id)
    {
        if (is_array($in_user_id)) {
            $where['up_user_id'] = ['IN', $in_user_id];
        } else {
            $where['up_user_id'] = $in_user_id;
        }
        $user_id_list = Db::name('user')->field('id')->where($where)->select();

        $user_id_arr = array_column($user_id_list, 'id');
        if ($user_id_arr) {
            $this->search_user_ids = array_merge($this->search_user_ids, $user_id_arr);
            return $this->getSonUserIds($user_id_arr);
        } else {
            return $this->search_user_ids;
        }
    }

    /**
     * 下级用户总累计业绩
     * @param int $user_id 用户id
     * @return float
     * */
    public function allConsume($user_id)
    {
        $son_user_ids = $this->getSonUserIds($user_id);
        if ($son_user_ids) {
            $all_consume = Db::name('order')->where(['user_id' => ['IN', $son_user_ids], 'is_pay' => 1, 'complete_time' => ['neq', 0]])->sum('pay_price');

        } else {
            $all_consume = 0;
        }

        return sprintf('%.2f', $all_consume);
    }

}